#include "stdafx.h"

extern WSASetLastError_proxy_t pTrueWSASetLastError;

int WSACleanup_proxy ( void )
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "WSACleanup");
        WSACleanup_in_inout WSACleanupIN;
        
        std::vector<char> out_buffer;
        Serialize(header, WSACleanupIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        WSACleanup_out_inout WSACleanupOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(WSACleanupOUT);

        if(WSACleanupOUT.wsa_last_error_ != 0)
        {
            pTrueWSASetLastError(WSACleanupOUT.wsa_last_error_);
            return SOCKET_ERROR;
        }
        return 0;
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "WSACleanup: " << ex.what();
    }
    pTrueWSASetLastError (WSAEWOULDBLOCK);
    return SOCKET_ERROR;
}

////////////////////////////////////////////////////////////////
int __WSAFDIsSet_proxy (
    SOCKET fd,
    fd_set *set
    )
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "__WSAFDIsSet");
        __WSAFDIsSet_in_inout __WSAFDIsSetIN(fd, set);
        
        std::vector<char> out_buffer;
        Serialize(header, __WSAFDIsSetIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        __WSAFDIsSet_out_inout __WSAFDIsSetOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(__WSAFDIsSetOUT);

        if(__WSAFDIsSetOUT.wsa_last_error_ != 0)
        {
            pTrueWSASetLastError(__WSAFDIsSetOUT.wsa_last_error_);
        }
        return __WSAFDIsSetOUT.ret_;
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "__WSAFDIsSet: " << ex.what();
    }
    pTrueWSASetLastError (WSAEWOULDBLOCK);
    //??? return SOCKET_ERROR;
    return 0; // false
}

////////////////////////////////////////////////////////////////
int WSAGetLastError_proxy ( void )
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "WSAGetLastError");
        WSAGetLastError_in_inout WSAGetLastErrorIN;
        
        std::vector<char> out_buffer;
        Serialize(header, WSAGetLastErrorIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        WSAGetLastError_out_inout WSAGetLastErrorOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(WSAGetLastErrorOUT);
        
        return WSAGetLastErrorOUT.ret_;
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "WSAGetLastError: " << ex.what();
    }
    return WSAEWOULDBLOCK;
}

////////////////////////////////////////////////////////////////
void WSASetLastError_proxy (
    __in  int iError
    )
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "WSASetLastError");
        WSASetLastError_in_inout WSASetLastErrorIN(iError);
        
        std::vector<char> out_buffer;
        Serialize(header, WSASetLastErrorIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        /*WSASetLastError_out_inout WSASetLastErrorOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(WSASetLastErrorOUT);*/
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "WSASetLastError: " << ex.what();
    }
}

////////////////////////////////////////////////////////////////
int WSAStartup_proxy (
    __in   WORD wVersionRequested,
    __out  LPWSADATA lpWSAData
)
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "WSAStartup");
        WSAStartup_in_inout WSAStartupIN(wVersionRequested);
        
        std::vector<char> out_buffer;
        Serialize(header, WSAStartupIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        WSAStartup_out_inout WSAStartupOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(WSAStartupOUT);

        if (lpWSAData)
        {
            memcpy (lpWSAData, &WSAStartupOUT.WSAData_, sizeof(WSAStartupOUT.WSAData_));
        }
        return WSAStartupOUT.ret_;
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "WSAStartup: " << ex.what();
    }
    return WSASYSNOTREADY;
}

////////////////////////////////////////////////////////////////
